package wml.clipstore.storage.clips;

import java.util.Collection;
import java.util.HashMap;
import java.util.Stack;

import wml.clipstore.base.Entity;
import CLIPSJNI.Environment;
import CLIPSJNI.InstanceAddressValue;
import CLIPSJNI.PrimitiveValue;

class ClipsGetter {

	private Environment clips;
	private InstanceWrapper wrapper;
	public ClipsGetter(Environment clips) {
		this.wrapper = new InstanceWrapper();
		this.clips = clips;
	}	

	public InstanceAddressValue getInstance(String className, String query) {
		try {
			StringBuilder find = new StringBuilder("(find-instance ((?ins ")
					.append(className).append(")) ").append(query).append(")");
			PrimitiveValue v = clips.eval(find.toString());
			InstanceAddressValue inv = (InstanceAddressValue) clips
					.eval("(instance-address " + v.get(0).toString() + ")");
			return inv;
		} catch (Exception e) {
			System.out.println(e);
			return null;
		}
	}
	

	public <T extends Entity> T getEntity(InstanceAddressValue address,
			Class<T> clazz) throws Exception {
		HashMap<String, Object> getted = new HashMap<String, Object>();
		Stack<ObjectAddress> toGet = new Stack<ObjectAddress>();
		T entity = clazz.newInstance();
		toGet.push(new ObjectAddress(address, entity));
		getted.put(address.toString(), entity);
		while (!toGet.isEmpty()) {
			ObjectAddress tg = toGet.pop();
			if (tg.getObject() instanceof Entity) {
				this.wrapper.loadEntity(tg, getted, toGet);
			} else if (tg.getObject() instanceof Collection) {
				this.wrapper.loadCollecion(tg, getted, toGet);
			}
		}
		return entity;
	}
}
